/**
 * 注意到题目条件的本质就是：
 * 将N个位分配到M个位置，不重复不遗漏
 * 因此等价于将N个球分配到M个盒中，且球异盒同
 * 因为本来盒子可以看作是不同的，需要乘以M!，但是由于题目要求有序
 * 且不可能存在相等元素，因此M!中只有一种符合条件，也就是说不要乘M!
 * 就等价于球异盒同的分配方法，即第二类斯特林数
 * 注意到N和M很大，所以用O(MlogN)的做法，而不是O(NM)
 */
#include <bits/stdc++.h>
using namespace std;

#include <bits/extc++.h>
using namespace __gnu_pbds;


using llt = long long;
using Real = double;
using vi = vector<int>;
using pii = pair<int, int>;

llt const MOD = 1000000000 + 7LL;

llt qpow(llt a, llt n){
    llt r = 1;
    while(n){
        if(n & 1) r = r * a % MOD;
        a = a * a % MOD;
        n >>= 1;
    }
    return r;
}

llt inv(llt a){return qpow(a, MOD - 2LL);}

array<array<llt, 10>, 10> Stir;
void init(){
    Stir[0][0] = 1;
    for(int i=1;i<10;++i){
        Stir[i][0] = 0;
        for(int j=1;j<=i;++j){
            Stir[i][j] = Stir[i - 1][j - 1] + j * Stir[i - 1][j];     
        }
    }
    return;
}

int N, M;

llt proc(){
    // if(N < 10 and M < 10){
    //     llt ans = Stir[N][M];
    //     return ans;       
    // }
    vector<llt> Fac(M + 1, 0LL);
    Fac[0] = 1LL;
    for(int i=1;i<=M;++i) Fac[i] = Fac[i - 1] * i % MOD;
    vector<llt> IFac(M + 1, 0LL);
    IFac[M] = inv(Fac[M]);
    for(int i=M-1;i>=0;--i) IFac[i] = IFac[i + 1] * (i + 1) % MOD;
    assert(IFac[0] == 1 and IFac[1] == 1);

    llt sgn = (M & 1) ? -1 : 1;
    llt ans = 0;
    for(int i=0;i<=M;++i){
        llt tmp = sgn * qpow(i, N) % MOD * IFac[i] % MOD * IFac[M - i] % MOD;
        ans = (ans + tmp) % MOD;
        sgn *= -1;
    }

    ans %= MOD;
    if(ans < 0) ans += MOD;
    
    return ans;
}

int main(){
#ifndef ONLINE_JUDGE
    freopen("z.txt", "r", stdin);
#endif
    ios::sync_with_stdio(false);cin.tie(nullptr);cout.tie(0);
    init();
    int nofkase = 1;
    // cin >> nofkase;
    while(nofkase--){
        cin >> N >> M;
        cout << proc() << "\n";
    }
    return 0;
}